{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# The `Structures` notebook  <a id=\"Structures\"></a>[<font size=1>(back to `Main.ipynb`)</font>](./Main.ipynb)\n",
    "\n",
    "This notebook gathers all structures -- and their related constructors -- that are used in the computation of the steady-state Ramsey allocation."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The notebook is organized as follows:\n",
    "\n",
    "1. the [`Economy` structure](#economy-struct) characterizing the economy parameters (computational input);\n",
    "2. the [`AiyagariSolution` structure](#Aiyagari) containing the characterization of the Aiyagari equilibrium, such as policy functions and stationary distribution (computational output);\n",
    "3. The [`TruncatedAllocation` structure](#Truncated) characterizing the truncated economy -- such as $\\xi$s or truncated allocation (computational output);\n",
    "4. The [`Ramsey` structure](#Ramsey) containing the characterization of the truncated Ramsey equilibrium, such as Lagrange multipliers or weights of the social welafre functions  (computational output). "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# The `Economy` structure <a id=\"economy\"></a>[<font size=1>(back to menu)</font>](#Structures)\n",
    "\n",
    "1. the [structure definition](#economy-struct),\n",
    "2. a [specific constructor](#economy-const) performing calibration."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Structure definition <a id=\"economy-struct\"></a>[<font size=1>(back to `Economy`)</font>](#economy)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "mutable struct Economy{T<:Real,T1<:Function,T2<:Function,T3<:Function,T4<:Function,T5<:Function,I<:Int64}\n",
    "    #=\n",
    "        *** parameters ***\n",
    "    =#\n",
    "    β::T              # discount factor\n",
    "    σ::T              # inverse of IES\n",
    "    χ::T              # scaling parameter for labor disutility\n",
    "    φ::T              # Frish elasticity\n",
    "    α::T              # capital share in production function\n",
    "    δ::T              # capital depreciation\n",
    "    κ::T              # progressive labor taxation (see text for description)\n",
    "    τ::T              # idem \n",
    "    τk::T             # linear labor tax\n",
    "    Tt::T             # lump-sum tax\n",
    "\n",
    "    \n",
    "    #=\n",
    "        *** utility functions ***\n",
    "    =#\n",
    "    u::T1             # utility function for consumption\n",
    "    u′::T2            # derivative of u\n",
    "    inv_u′::T3        # inverse of the derivative of u\n",
    "    u′′::T4           # second-order derivative of u \n",
    "    \n",
    "    # labor supply (comes from labor supply Euler equation)\n",
    "    l_supply::T5\n",
    "    \n",
    "    \n",
    "    #=\n",
    "        *** grid for asset choices ***\n",
    "    =#\n",
    "    na    ::I         # number of asset grid points\n",
    "    a_min ::T         # min asset holdings\n",
    "    a_max ::T         # max asset holdings    \n",
    "    aGrid ::Vector{T} # grid for asset choices\n",
    "\n",
    "    #=\n",
    "        *** productivity process ***\n",
    "    =#\n",
    "    n_ex_ante ::I    # number of ex ante types\n",
    "    nys   ::Vector{I} # vector of productivity levels per type\n",
    "    ωys   ::Vector{T} # ex-ante distribution of the types\n",
    "    ny    ::I         # number of productivity levels (=sum(nys))\n",
    "    ys    ::Vector{T} # productivity levels\n",
    "    Πy    ::Matrix{T} # transition matrix\n",
    "    Sy    ::Vector{T} # stationary distribution of size ny\n",
    "end"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Calibration via constructor <a id=\"economy-const\"></a>[<font size=1>(back to `Economy`)</font>](#economy)\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "function Economy(\n",
    "    α::T,\n",
    "    δ::T,\n",
    "    σ::T,\n",
    "    χ::T,\n",
    "    φ::T,\n",
    "    κ::T,\n",
    "    τ::T,\n",
    "    τk::T,\n",
    "    Tt::T,\n",
    "    KsY::T,               # capital-to-output ratio\n",
    "    na::I,                # length of the asset grid\n",
    "    a_min::T,             # min of asset grid\n",
    "    a_max::T,             # max of asset grid\n",
    "    curv_a::T,            # curv of the asset grid (exp)\n",
    "    n_ex_ante::I,         # nb of ex-ante types\n",
    "    yscales::Vector{T},   # vector of productivity levels (per type)\n",
    "    nys::Vector{I},       # vector of nb of states (per type)\n",
    "    ρys::Vector{T},       # vector of productivity persistences (per type)\n",
    "    σys::Vector{T},       # vector of productivity volatility (per type)\n",
    "    ωys::Vector{T},       # vector of type weights \n",
    "    alg_y::Symbol         # algorithm for discretizing the productivity process\n",
    "    ) where {T<:Real,I<:Int}\n",
    "    \n",
    "    β  = (one(T) + α/KsY - δ)^(-one(T))\n",
    "    wt = (one(T)-α) * ((1/β - (one(T)-δ))/α)^(α/(α-one(T)))\n",
    "\n",
    "    \n",
    "    #=\n",
    "        *** utility functions ***\n",
    "    =#\n",
    "    \n",
    "    u      = (c::T,l::T)  -> (σ ≈ one(T)) ? log(c - l^(1.0 + 1/φ)/(χ*(1.0 + 1/φ)) ) : (c - l^(1.0 + 1/φ)/(χ*(1.0 + 1/φ)) )^(one(T)-σ)/(one(T)-σ)::T\n",
    "    u′     = (c::T,l::T)  -> (c- l^(1.0 + 1/φ)/(χ*(1.0 + 1/φ))) ^(-σ)::T\n",
    "    \n",
    "    inv_u′ = (up::T,l::T) -> up^(-one(T)/σ) +l^(1.0 + 1/φ)/(χ*(1.0 + 1/φ)) ::T    #GHH :  gives c for a given up and l\n",
    "    \n",
    "    u′′    = (c::T,l::T) -> -σ*(c - l^(1.0 + 1/φ)/(χ*(1.0 + 1/φ)))^(-σ-one(T))::T\n",
    "    \n",
    "    l_supply = (wv::T,y::T) -> (χ*τ*wv*(y^τ))^(1.0/(1.0/φ + 1.0 - τ))::T # GHH \n",
    "    \n",
    "    \n",
    "    #=\n",
    "        *** grid for asset choices ***\n",
    "    =#    \n",
    "    \n",
    "    aGrid = a_min .+ (a_max-a_min)*(range(0.0, 1.0, length=na)).^curv_a\n",
    "    \n",
    "    \n",
    "    #= \n",
    "        *** productivity process ***\n",
    "    =#    \n",
    " \n",
    "    if alg_y ∉ [:tauchen, :rouwenhorst]\n",
    "        alg_y = :rouwenhorst\n",
    "        @info \"\"\"The discretization algorithm has not been recognized and is set to Tauchen. \n",
    "               Only two values are possible: :tauchen or :rouwenhorst\"\"\"\n",
    "    end\n",
    "    \n",
    "    ωys ./= sum(ωys)\n",
    "    \n",
    "    @assert n_ex_ante == length(nys) == length(ρys) == length(σys) == length(ωys) == length(yscales)\n",
    "    ys = zeros(T,sum(nys))\n",
    "    \n",
    "    Πy = zeros(T,sum(nys),sum(nys))\n",
    "    Sy = zeros(T,sum(nys))\n",
    "    \n",
    "    for i in eachindex(ρys)\n",
    "        ρy = ρys[i]\n",
    "        σy = σys[i]\n",
    "        mc = eval(alg_y)(nys[i], ρy, σy)\n",
    "        trans = truncMatrix(collect(mc.p), threshold=5*10^-5) \n",
    "        Πy[1+(i-1)*nys[i]:i*nys[i],1+(i-1)*nys[i]:i*nys[i]] = trans\n",
    "        ys[1+(i-1)*nys[i]:i*nys[i]] .= yscales[i]*exp.(mc.state_values)\n",
    "        Sy[1+(i-1)*nys[i]:i*nys[i]] .= (trans^10000)[1,:]\n",
    "        Sy[1+(i-1)*nys[i]:i*nys[i]] .*= ωys[i]*sum(Sy[1+(i-1)*nys[i]:i*nys[i]])\n",
    "    end\n",
    "    Sy ./= sum(Sy)\n",
    "    \n",
    "    return Economy{T,typeof(u),typeof(u′),typeof(inv_u′),typeof(u′′),typeof(l_supply),I}(\n",
    "        β,σ,χ,φ,α,δ,κ,τ,τk,Tt,\n",
    "        u,u′,inv_u′,u′′,l_supply,\n",
    "        na,a_min,a_max,aGrid,n_ex_ante,\n",
    "        nys,ωys,\n",
    "        sum(nys),ys,Πy,Sy)\n",
    "end \n",
    "\n",
    "function Economy(;\n",
    "    α::T,\n",
    "    δ::T,\n",
    "    σ::T,\n",
    "    χ::T,\n",
    "    φ::T,\n",
    "    κ::T,\n",
    "    τ::T,\n",
    "    τk::T,\n",
    "    Tt::T,\n",
    "    KsY::T,\n",
    "    na::I,\n",
    "    a_min::T, \n",
    "    a_max::T,     \n",
    "    curv_a::T,\n",
    "    n_ex_ante::I,\n",
    "    yscales::Vector{T}, \n",
    "    nys::Vector{I},\n",
    "    ρys::Vector{T}, \n",
    "    σys::Vector{T},\n",
    "    ωys::Vector{T},\n",
    "    alg_y::Symbol=:tauchen\n",
    "    ) where {T<:Real,I<:Int}\n",
    "    Economy(α,δ,σ,χ,φ,κ,τ,τk,Tt,KsY,na,a_min,a_max,curv_a,n_ex_ante,yscales,nys,ρys,σys,ωys,alg_y)\n",
    "end"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# The `AiyagariSolution` structure <a id=\"Aiyagari\"></a>[<font size=1>(back to menu)</font>](#Structures)\n",
    "\n",
    "This is a *mutable* structure containing the characterization of the Aiyagari equilibrium, such as policy functions and stationary distribution It is used an output of our computations. The Aiyagari equilibrium is computed in [`SolveAiyagari.ipynb`](./SolveAiyagari.ipynb). We proceed in two steps:\n",
    "\n",
    "1. the [structure definition](#Aiyagari-struct),\n",
    "2. a [specific constructor](#Aiyagari-const) performing calibration."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Structure definition <a id=\"Aiyagari-struct\"></a>[<font size=1>(back to `AiyagariSolution`)</font>](#Aiyagari)\n",
    "\n",
    "The structure contains the following elements.\n",
    "* Policy functions: $g_a$ (`ga`), $g_c$ (`ga`), $g_l$ (`ga`) for savings, consumption and labor supply respectively. They are implemented as $n_a \\times n_y$ matrices.\n",
    "* Pre- and post-tax gross interest and wage rates: $\\tilde R$ (`Rt`), $R$ (`R`), $\\tilde w$ (`wt`), $w$ (`w`). Pre-tax rates with a tilde.\n",
    "* Aggregate quantities: aggregate savings $A$, aggregate consumption $C$, capital $K$, aggregate labor supply $L$,  output $Y$,  public debt $B$, and public spending $G$ (computed endogenously for given rate).\n",
    "* Transition matrix `transitMat` on the product grid (asset $\\times$ productivity) of size $n_a\\cdot n_y \\times n_a\\cdot n_y$.\n",
    "* The stationary distribution `stationaryDist` associated to `transitMat`. It is implemented not as a $n_a\\cdot n_y$ vector but a $n_a\\times n_y$ matrix (as policy functions), which makes the link with the usual recursive approach simpler. \n",
    "* The residuals of the individual Euler equations, `residEuler` as a $n_a\\times n_y$ matrix. This is used in Dynare."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "mutable struct AiyagariSolution{T<:Real,I<:Integer}    \n",
    "    ga::Matrix{T}                    # policy function for savings on the asset grid\n",
    "    gl::Matrix{T}                    # policy function for labor on the asset grid\n",
    "    gc::Matrix{T}                    # policy function for consumption on the asset grid\n",
    "    Rt::T                            # pre-tax gross interest rate\n",
    "    wt::T                            # pre-tax wage rate\n",
    "    R::T                             # post-tax gross interest rate\n",
    "    w::T                             # post-tax wage rate\n",
    "    A::T                             # aggregate savings\n",
    "    C::T                             # aggregate consumption\n",
    "    K::T                             # aggregate capital\n",
    "    L::T                             # aggregate labor supply (in efficient units)\n",
    "    G::T                             # public spending\n",
    "    Y::T                             # GDP\n",
    "    B::T                             # public debt\n",
    "    transitMat::SparseMatrixCSC{T,I} # transition matrix\n",
    "    stationaryDist::Matrix{T}        # stationary distribution\n",
    "    residEuler::Matrix{T}            # residual of Euler equations\n",
    "end"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## The constructor <a id=\"Aiyagari-const\"></a>[<font size=1>(back to `AiyagariSolution`)</font>](#Aiyagari)\n",
    "\n",
    "The constructor is invoked by:\n",
    ">`AiyagariSolution(eco::Economy)`.\n",
    "\n",
    "The quantities are filled very basically and this does not matter much. The only point worth mentioning is about interest rates and wages that are filled as in the [`Economy` constructor](#economy-const). \n",
    "* The gross pre-tax interest rate is set via the golden rule: $\\tilde R = 1/\\beta$.\n",
    "* The post-tax rate is set using the capital tax: $R = 1 + (1-\\tau^k)(\\tilde R-1)$.\n",
    "* The pre-tax wage is set factor price equations and  the functional form of the production function:\n",
    "$\\tilde w = (1-\\alpha)(\\frac{\\beta^{-1}+ \\delta-1}{\\alpha})^{\\alpha/(\\alpha-1)}$. Using tax rates (see the paper for the precise reasons of the transformation), we obtain the post tax wage $w = \\frac{\\kappa}{1+\\tau^c}\\tilde w^{1-\\tau}$ (see the [`Economy` constructor](#economy-const) for further details).\n",
    "* The post-tax wage is set using the progressive taxation and accounts for the presence of consumption tax: $w = \\frac{\\kappa}{1+\\tau^c}\\tilde w^{1-\\tau}$ (see the paper for further details).\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "function AiyagariSolution(eco::Economy{T,T1,T2,T3,T4,T5,I}) where {T<:Real,\n",
    "            T1<:Function,T2<:Function,T3<:Function,T4<:Function,T5<:Function,I<:Int64}\n",
    "    @unpack β,α,δ,σ,l_supply,τk,τ,κ,ys,na,u′,ny,aGrid = eco\n",
    "    Rt = one(T)/β #  before-tax gross interest rate\n",
    "    wt = (one(T)-α) * ((Rt - (one(T)-δ))/α)^(α/(α-one(T)))\n",
    "    R  = one(T) + (one(T) - τk)*(Rt-one(T))\n",
    "    w  = κ*wt^τ\n",
    "    \n",
    "    cs = repeat(ys', outer=(na,1))\n",
    "    l_y= y::T ->  l_supply(w,y)\n",
    "    \n",
    "    ls = repeat(l_y.(ys)', outer=(na,1))\n",
    "    \n",
    "    as = repeat(aGrid, outer=(1,ny))\n",
    "    @assert size(cs) == size(ls) == size(as) == (na,ny)\n",
    "    L  = sum(@. ys*ls[1,:])\n",
    "    A  = sum(as)\n",
    "    return AiyagariSolution{T,I}(as,ls,cs,Rt,wt,R,w,A,A,A,L,\n",
    "                                    zero(T),A*L,zero(T),\n",
    "                                    spzeros(T, I, na*ny,na*ny), \n",
    "                                    fill(one(T)/(na*ny), na,ny), zeros(T,na,ny))\n",
    "end"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# The `TruncatedAllocation` structure <a id=\"Truncated\"></a>[<font size=1>(back to menu)</font>](#Structures)\n",
    "\n",
    "This is an *immutable* structure containing the characterization of the *truncated model*, such as truncation lengths, the truncated allocation, and the ξs (within heteroegneity parameters). The truncated model is computed in [`Truncation.ipynb`](./Truncation.ipynb). Again, there aretwo steps:\n",
    "\n",
    "1. the [structure definition](#Truncated-struct),\n",
    "2. a set of [specific constructors](#Truncated-const) that only aim to allow for keyword definitions for structures."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Structure definition <a id=\"Truncated-struct\"></a>[<font size=1>(back to `TruncatedAllocation`)</font>](#Truncated)\n",
    "\n",
    "The parent structure is `TruncatedModel`, which  contains the following elements.\n",
    "* the uniform truncation length `N::I`;\n",
    "* the vector of refined truncation length `refiNs::Vect{I}` (the history of the agent staying in state `ys[i]` is refined at least up to length `N` and to length `refiNs[i]`);\n",
    "* the total number of truncated histories with positive size `Ntot::I`;\n",
    "* the indices of the positive size histories `ind_h::Vect{I}`;\n",
    "* the truncated allocation `truncatedAllocation::TruncatedAllocation{I,T}`\n",
    "* the $\\xi$s `ξs::ξs_struct{T}`.\n",
    "\n",
    "The two sub-structures are `TruncatedAllocation` and `ξs_struct`. \n",
    "\n",
    "The structure `TruncatedAllocation` contains the truncated allocation, as vectors. For instance, `S_h` is the vector of the size of truncated histories, or `c_h`is the vector of consumption levels. The non-vector elements include the transition matrix over truncated histories, `Π_h` and the number of truncated histories `nb_cc_h`. The indices of truncated histories is given in teh integer vector `ind_cc_h`. Note that all double vectors have exactly the same size (equal to `Ntot`, the number of truncated histories). \n",
    "\n",
    "The sttructure `ξs_struct` contains the various ξs that are needed in the model. For instance, `ξu0` is related to the aggregation of $u$, while `ξy` is related to the aggregation of income in the presence of progressive taxation."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "struct TruncatedAllocation{I<:Integer,T<:Real}\n",
    "    S_h::Vector{T}       # size of truncated histories\n",
    "    Π_h::SparseMatrixCSC{T,I}# transition matrix for histories\n",
    "    statDist_h::Matrix{T}#stationary distribution \n",
    "    y0_h::Vector{T}      # current productivity levels\n",
    "    ind_y0_h::Vector{I}  # indices of current productivity levels\n",
    "    a_beg_h::Vector{T}   # beginning-of-period wealth per history and per capita\n",
    "    a_end_h::Vector{T}   # end-of-period wealth per history and per capita\n",
    "    c_h::Vector{T}       # consumption per history and per capita\n",
    "    l_h::Vector{T}       # labor supply per history and per capita\n",
    "    ly_τ_h::Vector{T}    # (l y)^τ\n",
    "    u_h::Vector{T}       # utility of consumption per history and per capita\n",
    "    u′_h::Vector{T}      # marginal utility of consumption per history and per capita\n",
    "    u′′_h::Vector{T}     # second-order derivative of utility of consumption per history and per capita\n",
    "    v_h::Vector{T}       # utility of labor per history and per capita\n",
    "    v′_h::Vector{T}      # marginal utility of labor per history and per capita\n",
    "    resid_E_h::Vector{T} # Euler Lagrange multiplier at the history level\n",
    "    nb_cc_h::I           # nb of credit constrained histories\n",
    "    ind_cc_h::Vector{I}  # indices of credit constrained histories\n",
    "    share :: Vector{T}   # mass of CC agents by types\n",
    "end\n",
    "\n",
    "struct ξs_struct{T<:Real}\n",
    "    ξu0::Vector{T}\n",
    "    ξu1::Vector{T}\n",
    "    ξu2::Vector{T}\n",
    "    ξuE::Vector{T}\n",
    "    ξy ::Vector{T}\n",
    "    ξv0::Vector{T}\n",
    "    ξv1::Vector{T}\n",
    "end  \n",
    "\n",
    "struct TruncatedModel{I<:Integer,T<:Real}\n",
    "    N::I\n",
    "    refiNs::Vector{I}\n",
    "    Ntot::I\n",
    "    ind_h::Vector{I}\n",
    "    ind_hs::Vector{Vector{I}}\n",
    "    truncatedAllocation::TruncatedAllocation{I,T}\n",
    "    ξs::ξs_struct{T}\n",
    "end"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Constructors <a id=\"Truncated-const\"></a>[<font size=1>(back to `TruncatedAllocation`)</font>](#Truncated)\n",
    "\n",
    "The constructors for `TruncatedAllocation`, `ξs_struct`, and `TruncatedModel` simply allow one to use keyword definitions for these structures. They do not perform any actual computation. The keywords are the same as in the structure definitions. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "function TruncatedAllocation(;S_h::Vector{T}, Π_h::SparseMatrixCSC{T,I},statDist_h::Matrix{T}, y0_h::Vector{T}, \n",
    "        ind_y0_h::Vector{I},a_beg_h::Vector{T}, a_end_h::Vector{T}, c_h::Vector{T}, l_h::Vector{T}, ly_τ_h::Vector{T}, \n",
    "        u_h::Vector{T}, u′_h::Vector{T}, u′′_h::Vector{T}, v_h::Vector{T}, v′_h::Vector{T}, \n",
    "        resid_E_h::Vector{T}, nb_cc_h::I, ind_cc_h::Vector{I},share::Vector{T}) where{I<:Integer,T<:Real}\n",
    "    TruncatedAllocation{I,T}(S_h,Π_h,statDist_h,y0_h,ind_y0_h,a_beg_h,a_end_h,c_h,l_h,ly_τ_h,u_h,u′_h,u′′_h,\n",
    "            v_h,v′_h,resid_E_h, nb_cc_h,ind_cc_h,share)    \n",
    "end\n",
    "\n",
    "function ξs_struct(;ξu0::Vector{T},ξu1::Vector{T},ξu2::Vector{T},ξuE::Vector{T},\n",
    "            ξy::Vector{T},ξv0::Vector{T},ξv1::Vector{T}) where{T<:Real}\n",
    "    ξs_struct{T}(ξu0,ξu1,ξu2,ξuE,ξy,ξv0,ξv1)\n",
    "end  \n",
    "\n",
    "function TruncatedModel(;N::I,refiNs::Vector{I},Ntot::I,ind_h::Vector{I},ind_hs::Vector{Vector{I}},\n",
    "        truncatedAllocation::TruncatedAllocation{I,T},ξs::ξs_struct{T}) where {I<:Integer,T<:Real}\n",
    "    TruncatedModel{I,T}(N,refiNs,Ntot,ind_h,ind_hs,truncatedAllocation,ξs)\n",
    "end"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# The `Ramsey` structure <a id=\"Ramsey\"></a>[<font size=1>(back to menu)</font>](#Structures)\n",
    "\n",
    "This is an *immutable* structure containing the characterization of the *truncated Ramsey model*, such as wights and Lagrange multiplies. The Ramsey truncated model is computed in [`Ramsey.ipynb`](./Ramsey.ipynb). Again, there are two steps:\n",
    "\n",
    "1. the [structure definition](#Ramsey-struct),\n",
    "2. a set of [specific constructors](#Ramsey-const) that only aim to allow for keyword definitions for structures."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Structures <a id=\"Ramsey-struct\"></a>[<font size=1>(back to `Ramsey`)</font>](#Ramsey)\n",
    "\n",
    "The parent structure is `Ramsey`, which  contains the following elements.\n",
    "* the weights of the social welfare function, `weights::Weights`;\n",
    "* the the Lagrange multipliers of the Ramsey program `lagrangeMult::LagrangeMult`;\n",
    "* the truncated model `truncatedModel::TruncatedModel` (this simply repeats the truncated model  that has already been computed -- it is mostly for convenience and not performance). \n",
    "\n",
    "The two sub-structures are `Weights` and `LagrangeMult`.\n",
    "* `Weights` contains the Pareto weights of the social welfare function. The structure contains the non-parametric weights per productivity level $y$:  $(\\omega_y)_y$,  represented by `ω` and $(\\overline{\\omega}_{y})_y = ( S_y \\omega_{y})_y$,  represented by `ωb`. It also constains the weights per history $h$: $(\\omega_h)_h$ (`ω_h`) and $(\\overline{\\omega}_{h})_h = ( S_h \\omega_{h})_h$ (represented by `ωb_h`). The parametric weights are also specified and noted with a suffix `_param` (e.g., `ω_param` or `ωb_param`).\n",
    "* `LagrangeMult` contains the Lagrange multipliers of the Ramsey program and some of their transforms. The `b`subscript refers to the history wise variable. For instance, the Lagrange multiplier on the Euler equation  $(\\lambda_{c,h})_h$ is represented by the vector `λc`, $(\\overline{\\lambda}_{c,h})_h = ( S_h \\lambda_{c,h})_h$ is represented  by `λcb`, and $(\\tilde{\\lambda}_{c,h})_h = (\\sum_{\\tilde h} \\Pi_{{\\tilde h} h} \\lambda_{c,\\tilde h})_h$ is represented  by `λct`. Same for the Lagrange multiplier on the labor FOC $(\\lambda_{l,h})$ represented by `λl`, plus `λlb` and `λlt`. For the marginal value of liquidity $(\\psi_{h})_y$ represented by the vector `ψ`, only add $(\\overline{\\psi}_{h})_h$ represented by  `ψb`. For the Lagrange mutiplier $\\mu$ on the government budget constraint, it is represented by the scalar `μ` (but no transform).\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "struct Weights{T<:Real}\n",
    "    ω         ::Vector{T} \n",
    "    ωb        ::Vector{T}\n",
    "    ω_h       ::Vector{T}\n",
    "    ωb_h      ::Vector{T}\n",
    "    ω_param   ::Vector{T} \n",
    "    ωb_param  ::Vector{T}\n",
    "    ω_param_h ::Vector{T} \n",
    "    ωb_param_h::Vector{T}\n",
    "end \n",
    "struct LagrangeMult{T<:Real}\n",
    "    λc ::Vector{T}\n",
    "    λct::Vector{T}\n",
    "    λcb::Vector{T}\n",
    "    λl ::Vector{T}\n",
    "    λlt::Vector{T}\n",
    "    λlb::Vector{T}\n",
    "    μ  ::T\n",
    "    ψ  ::Vector{T}\n",
    "    ψb  ::Vector{T}\n",
    "end \n",
    "struct Ramsey{I<:Integer,T<:Real}\n",
    "    weights       ::Weights{T}\n",
    "    lagrangeMult  ::LagrangeMult{T}\n",
    "    truncatedModel::TruncatedModel{I,T}\n",
    "    l::T  # labor supply with prod 1 for Ramsey\n",
    "end"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Constructor  <a id=\"Ramsey-const\"></a>[<font size=1>(back to `Ramsey`)</font>](#Ramsey)\n",
    "\n",
    "As for `TruncatedAllocation`, the constructors for `Ramsey`, `LagrangeMult`, and `Weights` simply allow one to use keyword definitions for these structures. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "function Weights(;ω::Vector{T},ωb::Vector{T},ω_h::Vector{T},ωb_h::Vector{T},\n",
    "                  ω_param::Vector{T},ωb_param::Vector{T},ω_param_h::Vector{T},ωb_param_h::Vector{T}) where{T<:Real}\n",
    "    Weights(ω,ωb,ω_h,ωb_h,ω_param,ωb_param,ω_param_h,ωb_param_h)\n",
    "end \n",
    "function LagrangeMult(;λc::Vector{T},λct::Vector{T},λcb::Vector{T},\n",
    "                       λl::Vector{T},λlt::Vector{T},λlb::Vector{T},μ::T,\n",
    "                       ψ::Vector{T},ψb::Vector{T}) where{T<:Real}\n",
    "    LagrangeMult(λc,λct,λcb,λl,λlt,λlb,μ,ψ,ψb)\n",
    "end \n",
    "function Ramsey(;weights::Weights{T},lagrangeMult::LagrangeMult{T},\n",
    "                 truncatedModel::TruncatedModel{I,T},l::T) where{I<:Integer,T<:Real}\n",
    "    Ramsey(weights,lagrangeMult,truncatedModel,l)\n",
    "end"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Julia 1.10.5",
   "language": "julia",
   "name": "julia-1.10"
  },
  "language_info": {
   "file_extension": ".jl",
   "mimetype": "application/julia",
   "name": "julia",
   "version": "1.10.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
